package com.chunyu.ask.config;
 
 
import java.lang.reflect.Method;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

//启用redis注解
//@Configuration
//@EnableCaching
//@PropertySource(value = "classpath:/redis.properties")
public class RedisConfig extends CachingConfigurerSupport {

	  @Value("${spring.redis.host}")
	  private String host;
	  @Value("${spring.redis.port}")
	  private int port;
	  @Value("${spring.redis.timeout}")
	  private int timeout;
	   
	  @Bean
	  public KeyGenerator wiselyKeyGenerator(){
	      return new KeyGenerator() { 
	          public Object generate(Object target, Method method, Object... params) {
	              StringBuilder sb = new StringBuilder();
	              sb.append(target.getClass().getName());
	              sb.append(method.getName());
	              for (Object obj : params) {
	                  sb.append(obj.toString());
	              }
	              return sb.toString();
	          }
	      };
	  }
	  
	  @Bean
	  public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
	      StringRedisTemplate template = new StringRedisTemplate(factory);
	      setSerializer(template); //设置序列化工具，这样ReportBean不需要实现Serializable接口
	      template.afterPropertiesSet();
	      return template;
	  }
	  private void setSerializer(StringRedisTemplate template) {
	      Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
	      ObjectMapper om = new ObjectMapper();
	      om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
	      om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
	      jackson2JsonRedisSerializer.setObjectMapper(om);
	      template.setValueSerializer(jackson2JsonRedisSerializer);
	  }
	   
	  @Bean
	  public JedisConnectionFactory redisConnectionFactory() {
		  //配置连接redis服务器
	      JedisConnectionFactory factory = new JedisConnectionFactory();
	      factory.setHostName(host);
	      factory.setPort(port);
	      factory.setTimeout(timeout); //设置连接超时时间
	      return factory;
	  }
	  @Bean
	  public CacheManager cacheManager(RedisTemplate redisTemplate) {
	      RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
	      // Number of seconds before expiration. Defaults to unlimited (0)
	      cacheManager.setDefaultExpiration(100); //设置key-value超时时间 N秒， 测试时可以设置短点
	      return cacheManager;
	  } 
 
}
